package com.mini.grpc.client;

import com.mini.grpc.common.Metadata;
import com.mini.grpc.common.MethodDescriptor;
import com.mini.grpc.common.Status;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * ClientInterceptors提供了处理客户端拦截器的静态方法。
 */
public final class ClientInterceptors {
    
    private ClientInterceptors() {}
    
    /**
     * 使用拦截器拦截通道
     *
     * @param channel 原始通道
     * @param interceptors 拦截器数组
     * @return 拦截后的通道
     */
    public static MiniGrpcChannel interceptChannel(MiniGrpcChannel channel, ClientInterceptor... interceptors) {
        return interceptChannel(channel, Arrays.asList(interceptors));
    }
    
    /**
     * 使用拦截器拦截通道
     *
     * @param channel 原始通道
     * @param interceptors 拦截器列表
     * @return 拦截后的通道
     */
    public static MiniGrpcChannel interceptChannel(MiniGrpcChannel channel, List<ClientInterceptor> interceptors) {
        if (interceptors.isEmpty()) {
            return channel;
        }
        return new InterceptingChannel(channel, interceptors);
    }
    
    /**
     * 使用拦截器拦截调用
     *
     * @param call 原始调用
     * @param interceptor 拦截器
     * @param method 方法描述符
     * @param callOptions 调用选项
     * @param <ReqT> 请求类型
     * @param <RespT> 响应类型
     * @return 拦截后的调用
     */
    public static <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
            ClientCall<ReqT, RespT> call,
            ClientInterceptor interceptor,
            MethodDescriptor<ReqT, RespT> method,
            CallOptions callOptions) {
        return interceptor.interceptCall(method, callOptions, new MiniGrpcChannel() {
            @Override
            public <ReqT1, RespT1> ClientCall<ReqT1, RespT1> newCall(
                    MethodDescriptor<ReqT1, RespT1> method, CallOptions callOptions) {
                @SuppressWarnings("unchecked")
                ClientCall<ReqT1, RespT1> typedCall = (ClientCall<ReqT1, RespT1>) call;
                return typedCall;
            }
            
            @Override
            public ConnectivityState getState(boolean requestConnection) {
                throw new UnsupportedOperationException();
            }
            
            @Override
            public MiniGrpcChannel shutdown() {
                throw new UnsupportedOperationException();
            }
            
            @Override
            public boolean isShutdown() {
                throw new UnsupportedOperationException();
            }
            
            @Override
            public boolean isTerminated() {
                throw new UnsupportedOperationException();
            }
        });
    }
    
    /**
     * 拦截通道，用于应用拦截器
     */
    private static final class InterceptingChannel implements MiniGrpcChannel {
        
        private final MiniGrpcChannel channel;
        private final List<ClientInterceptor> interceptors;
        
        /**
         * 创建一个新的InterceptingChannel
         *
         * @param channel 原始通道
         * @param interceptors 拦截器列表
         */
        public InterceptingChannel(MiniGrpcChannel channel, List<ClientInterceptor> interceptors) {
            this.channel = channel;
            this.interceptors = Collections.unmodifiableList(new ArrayList<>(interceptors));
        }
        
        @Override
        public <ReqT, RespT> ClientCall<ReqT, RespT> newCall(
                MethodDescriptor<ReqT, RespT> method, CallOptions callOptions) {
            ClientCall<ReqT, RespT> call = channel.newCall(method, callOptions);
            
            // 按照顺序应用拦截器
            for (ClientInterceptor interceptor : interceptors) {
                call = interceptCall(call, interceptor, method, callOptions);
            }
            
            return call;
        }
        
        @Override
        public ConnectivityState getState(boolean requestConnection) {
            return channel.getState(requestConnection);
        }
        
        @Override
        public MiniGrpcChannel shutdown() {
            channel.shutdown();
            return this;
        }
        
        @Override
        public boolean isShutdown() {
            return channel.isShutdown();
        }
        
        @Override
        public boolean isTerminated() {
            return channel.isTerminated();
        }
    }
    
    /**
     * 拦截调用，用于应用拦截器
     *
     * @param <ReqT> 请求类型
     * @param <RespT> 响应类型
     */
    public static class InterceptingCall<ReqT, RespT> implements ClientCall<ReqT, RespT> {
        
        private final ClientCall<ReqT, RespT> delegate;
        
        /**
         * 创建一个新的InterceptingCall
         *
         * @param delegate 委托调用
         */
        public InterceptingCall(ClientCall<ReqT, RespT> delegate) {
            this.delegate = delegate;
        }
        
        @Override
        public void start(Listener<RespT> responseListener, Metadata headers) {
            delegate.start(responseListener, headers);
        }
        
        @Override
        public void request(int numMessages) {
            delegate.request(numMessages);
        }
        
        @Override
        public void sendMessage(ReqT message) {
            delegate.sendMessage(message);
        }
        
        @Override
        public void halfClose() {
            delegate.halfClose();
        }
        
        @Override
        public void cancel(String message, Throwable cause) {
            delegate.cancel(message, cause);
        }
        
        @Override
        public boolean isCancelled() {
            return delegate.isCancelled();
        }
    }
} 